﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using GS1.Entidad;
using GS1.Utilitario;
using System.Configuration;
using System.Xml;
using System.Security.Cryptography.X509Certificates;

namespace ControlVehiculoRFIDPA
{
    public class ConexionREST
    {
        #region --- Variables y Constantes ----
        // URL Servicio REST (Local)
        private static string SERVICIO_REST_URL = ConfigurationManager.AppSettings[Constantes.URL_SERVICIO];
        private static string SERVICIO_REST_ACTION = ConfigurationManager.AppSettings[Constantes.ACTION_SERVICIO];

        // Tiempo de espera de respuesta del Servicio REST
        private static int SERVICO_REST_TIEMPO_ESPERA = ConfigurationManager.AppSettings[Constantes.TIEMPO_ESPERA].ToEntero();
        //35000;
        #endregion

        #region --- Metodos Propios ---
        /// <summary>
        /// Metodo: Que permite enviar una operacion al servicio REST
        /// </summary>
        /// <param name="operacion">Operacion a enviar al servicio</param>
        /// <returns>Trama obtenida como resultado</returns>
        public string ejecutarTrama(Operacion operacion)
        {
            try
            {
                #region ----Envio-----
                // Estableciendo la URL del servicio REST
                XmlDocument soapEnvelopeXml = CreateSoapEnvelope(operacion);
                HttpWebRequest webRequest = CreateWebRequest();
                InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);

                // Inicia el llamado de manera asincrona
                IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);

                // Se detiene todo el hilo hasta que se termine la tarea.
                asyncResult.AsyncWaitHandle.WaitOne();
                #endregion

            }
            catch (WebException)
            {
                throw new Exception("No hay conexión con el Servidor Principal" + Environment.NewLine +
                                    "Por favor verifique si tiene acceso a la red de la empresa.");
            }

            return " ";
        }

        #region  --- Metodos para enviar XML --

        private static HttpWebRequest CreateWebRequest()
        {
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(SERVICIO_REST_URL);

            X509Certificate cert = X509Certificate.CreateFromCertFile("C://cert//xxx.cer");
            webRequest.ClientCertificates.Add(cert);

            NetworkCredential nc = new NetworkCredential("", ""); //USER Y PASSWORD DE WS
            webRequest.Credentials = nc;
            webRequest.Headers.Add("SOAPAction", SERVICIO_REST_ACTION); //CAMBIAR SOAPACTION SERVICIOACTION
            webRequest.ContentType = "text/xml;charset=\"utf-8\"";
            webRequest.Accept = "text/xml";
            webRequest.Method = "POST";
            return webRequest;
        }

        private static XmlDocument CreateSoapEnvelope(Operacion operacion)
        {
            XmlDocument soapEnvelop = new XmlDocument();
            string xmlRequest = String.Concat(
                "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:req=\"http://hermes.com.pe/schema/common/types/requestmetada\" xmlns:con=\"http://hermes.com.pe/schema/rfid/ControlVehiculoRFID\">",
                "  <soapenv:Header>",
                "    <req:requestMetada>",
                "      <!--Optional:-->",
                "      <req:user>", operacion.requestMetadata.user, "</req:user>",
                "      <req:remoteHost>", operacion.requestMetadata.remoteHost, "</req:remoteHost>",
                "    </req:requestMetada>",
                "  </soapenv:Header>",
                "  <soapenv:Body>",
                "    <con:registrarMovimientoRFIDRequest>",
                "      <con:codigoEPC>", operacion.controlVehiculoRFID.codigoEPC.Replace(" ", ""), "</con:codigoEPC>",
                "      <con:codigoDireccionVehiculo>", operacion.controlVehiculoRFID.codigoDireccionVehiculo, "</con:codigoDireccionVehiculo>",
                "      <!--Optional:-->",
                "      <con:descripcionPuerta>", operacion.controlVehiculoRFID.descripcionPuerta, "</con:descripcionPuerta>",
                "      <con:fechaInicioMovimiento>", operacion.controlVehiculoRFID.fechaInicioMovimiento.ToString("yyyy-MM-ddTHH':'mm':'ss"), "</con:fechaInicioMovimiento>",
                "      <con:fechaFinalMovimiento>", operacion.controlVehiculoRFID.fechaFinalMovimiento.ToString("yyyy-MM-ddTHH':'mm':'ss"), "</con:fechaFinalMovimiento>",
                "   </con:registrarMovimientoRFIDRequest>",
                "  </soapenv:Body>",
                "</soapenv:Envelope>");

            soapEnvelop.LoadXml(xmlRequest);
            return soapEnvelop;
        }

        private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
        {
            using (Stream stream = webRequest.GetRequestStream())
            {
                soapEnvelopeXml.Save(stream);
            }
        }

        #endregion

        #endregion
    }
}
